package in.ac.iiitd.cse201.Devansh2011042.finallabexam;

import in.ac.iiitd.cse201.Devansh2011042.finallabexam.KeyNotFoundException;
import java.util.Iterator;
import java.util.Map;

/**
 * This is the abstract base class for all forms of simple buffer management
 * simulations. Concrete buffer management policies such as LRU, LRU-K, MRU,
 * etc. can be implemented by extending this class and providing additional
 * implementations.
 *
 * @author bedathur
 */
public abstract class BufferManager<T> implements Iterable {

    /**
     * A Map of all the current BufferSlots in the buffer manager. BufferSlots
     * are indexed by the address of the page they contain.
     */
    protected Map<Integer, BufferSlot<? extends T>> keys;

    /**
     * remove a page with from the pool of pages in memory and return void 
     * to the calling program. MR: Method does not return reference.
     */
    protected abstract void evictPage();

    /**
     * insert a page into the buffer pool after verifying that the given page is
     * not in the buffer pool already.
     *
     * @param slot
     */
    public abstract void insertPage(BufferSlot<? extends T> slot);

    /**
     * Get reference to the payload of a page specified by the key. There can be
     * multiple threads/processes which have reference to a page at any time. A
     * page which has active references to a page cannot be removed from the
     * bufferpool at any time.
     *
     * @param key
     */
    public abstract T getReference(int key) throws KeyNotFoundException;

    /**
     * Release a reference to a page specified by the key. This essentially
     * decrements the reference count for the specified page.
     *
     * @param key
     */
    public abstract void releaseReference(int key) throws KeyNotFoundException;

    /**
     * **** Testing routines ***********************************************
     * The following routines must be implemented correctly in order to be able
     * to test and evaluate your program. NOTE THAT EVEN IF YOUR LOGIC IS
     * CORRECT, IF THE FOLLOWING ROUTINES ARE NOT IMPLEMENTED CORRECTLY, THEN
     * YOU WILL NOTE BE AWARDED MARKS.
     */
    /**
     * Provides a thread-safe iterator over all the BufferSlots in the Buffer
     * Manager at the time of calling this method. The iteration order is
     * dependent on the underlying buffer management policy. It is required that
     * the order be the same as the order in which BufferSlots will be
     * considered for eviction.
     */
    @Override
    public Iterator<BufferSlot<? extends T>> iterator() {
        throw new Error("Must be overridden by a concrete subclass");
    }

    /**
     * Returns the total number of BufferSlots currently held in the Buffer
     * Manager. Clearly, the result should not exceed the capacity of the
     * bufferpool specified.
     */
    public int getCount() {
        return keys.keySet().size();
    }
}
